package com.study.manage.mvc.org.competition;

import java.io.OutputStreamWriter;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.study.manage.dal.BlogBehaviorRepository;
import com.study.manage.dal.EvaluateApplyRepository;
import com.study.manage.dal.EvaluateApplyWorkRepository;
import com.study.manage.dal.EvaluateGroupDetailRepository;
import com.study.manage.dal.EvaluateNewRepository;
import com.study.manage.dal.EvaluateRepository;
import com.study.manage.dal.EvaluateSingupPoolRepository;
import com.study.manage.dal.NewsRepository;
import com.study.manage.dal.OrderRepository;
import com.study.manage.dal.UserOrganizaRepository;
import com.study.manage.domain.Evaluate;
import com.study.manage.domain.News;
import com.study.manage.domain.enumm.EvaluateApplyVerifyState;
import com.study.manage.domain.enumm.EvaluateNewType;
import com.study.manage.domain.enumm.LiveDieState;
import com.study.manage.dto.AjaxResponse;
import com.study.manage.dto.JsonResponseBean;
import com.study.manage.dto.SessionUser;
import com.study.manage.mvc.common.BaseController;
import com.study.manage.mvc.common.CommonService;
import com.study.manage.utils.DateTimeUtil;
import com.study.manage.utils.MapUtils;


@Controller
@RequestMapping("org/evaluate/detail")
public class CompetitionstageController extends BaseController {

    @Autowired
    private UserOrganizaRepository userOrganizaRepository;
    @Autowired
    private EvaluateGroupDetailRepository evaluateGroupDetailRepository;
    @Autowired
    private EvaluateApplyRepository evaluateApplyRepository;
    @Autowired
    private EvaluateRepository evaluateRepository;
    @Autowired
    private EvaluateNewRepository evaluateNewRepository;
    @Autowired
    private EvaluateSingupPoolRepository evaluateSingupPoolRepository;
    @Autowired
    private EvaluateApplyWorkRepository evaluateApplyWorkRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private BlogBehaviorRepository blogBehaviorRepository;
    @Autowired
    private CommonService commonService;


    @RequestMapping(path = "info", method = RequestMethod.GET)
    public String info() {
        return "org/evaluate/competitionstage";
    }

    @ResponseBody
    @RequestMapping(path = "info-detail", method = RequestMethod.GET)
    public AjaxResponse info(Long id) {

        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = (SessionUser) session.getAttribute("user");
        Evaluate evaluate = evaluateRepository.findOne(id);
        Map<String, Object> map = MapUtils.convert(evaluate);
        map.put("imgUrl", evaluate.coverUrl);
        map.put("userOrganizaName", su.getName());
        return ajax.setObj(map);
    }

    @ResponseBody
    @RequestMapping(path = "info-evaluteCount", method = RequestMethod.GET)
    public AjaxResponse info_evaluteCount(Long id) {

        AjaxResponse ajax = new AjaxResponse(true);
        List<Long> evaluateIds = new ArrayList<>(Arrays.asList(id));
        Map<String, Object> map = new HashMap<>();
        map.put("applyCount", evaluateApplyRepository.countByEvaluateIdAndDay(id, null));
        map.put("blogCount",
                evaluateApplyWorkRepository.countByEvaluateIdInAndDay(evaluateIds, null));
        map.put("jjCount", evaluateApplyRepository.countByIdAndVerifyAndVerifyState(id, null,
                EvaluateApplyVerifyState.JJ));
        map.put("hxCount",
                evaluateSingupPoolRepository.countByEvaluateIdAndState(id, LiveDieState.LIVE));
        Float orderSum = orderRepository.sumPriceByEvaluateIdIn(evaluateIds, null);
        map.put("totalPrice", orderSum == null ? 0 : orderSum);
        Float otherTotalPrice = orderRepository.sumOtherPriceByEvaluateIdAndDate(evaluateIds, null);
        map.put("totalPrice", orderSum == null ? 0 : orderSum);
        map.put("otherTotalPrice", otherTotalPrice == null ? 0 : otherTotalPrice);
        return ajax.setObj(map);
    }

    @ResponseBody
    @RequestMapping(path = "info-detail-count", method = RequestMethod.GET)
    public AjaxResponse list_detail_count(Long id) {

        AjaxResponse ajax = new AjaxResponse(true);
        List<Long> es = new ArrayList<>(Arrays.asList(id));
        Map<String, Object> map = commonService.getCountNum(es, null);
        return ajax.setObj(map);
    }

    @ResponseBody
    @RequestMapping(path = "info-detail-count-detail", method = RequestMethod.GET)
    public JsonResponseBean info_detail_count_detail(Integer flg,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginAt,
            @RequestParam(defaultValue = "BM") String type,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date endAt, Long id) {

        List<Long> evaluateIds = new ArrayList<>(Arrays.asList(id));
        Map<String, Date> timeMap = commonService.getTimes(beginAt, endAt, evaluateIds, flg);
        beginAt = timeMap.get("beginAt");
        endAt = timeMap.get("endAt");
        session.setAttribute("beginAt", beginAt);
        session.setAttribute("endAt", endAt);
        List<Object[]> objs = getDataByType(type, evaluateIds, beginAt, endAt);
        List<Map<String, Object>> list = getReturnList(beginAt, endAt, objs);
        return new JsonResponseBean(list, true);
    }

    @Autowired
    private NewsRepository newsRepository;

    @ResponseBody
    @RequestMapping(path = "info-detail-newList", method = RequestMethod.GET)
    public AjaxResponse info_detail_new(HttpServletRequest request, EvaluateNewType type,
            Long evaluateId,
            @PageableDefault(sort = {"createdAt"}, direction = Direction.DESC) Pageable pageable) {
        SessionUser su = this.getUserInfo();
        AjaxResponse ajax = new AjaxResponse(true);
        Page<News> page =
                newsRepository.findByTypeInAndUserId(Arrays.asList(type), su.getId(), pageable);
        return ajax.setObj(page.getContent());
    }

    @RequestMapping(path = "exportExecl", method = RequestMethod.GET)
    public void exportExecl(Long id, String type, HttpServletResponse response) throws Exception {

        List<Long> evaluateIds = new ArrayList<>(Arrays.asList(id));
        Date beginAt = (Date) session.getAttribute("beginAt");
        Date endAt = (Date) session.getAttribute("endAt");
        List<Object[]> objList = getDataByType(type, evaluateIds, beginAt, endAt);
        List<Map<String, Object>> list = getReturnList(beginAt, endAt, objList);
        String nowDate = null;
        StringBuilder context = null;
        if ("BM".equals(type)) {
            nowDate = "报名人数.csv";
            context = new StringBuilder("日期,报名人数（提交）,报名过审人数,报名成功人数,报名收费,已拒绝,待审核\n");
            for (int i = 0; i < list.size(); i++) {
                Object A = list.get(i).get("date");
                Object B = list.get(i).get("报名人数（提交）") == null ? 0 : list.get(i).get("报名人数（提交）");
                Object C = list.get(i).get("报名过审人数") == null ? 0 : list.get(i).get("报名过审人数");
                Object D = list.get(i).get("报名成功人数") == null ? 0 : list.get(i).get("报名成功人数");
                Object E = list.get(i).get("报名收费") == null ? 0 : list.get(i).get("报名收费");
                Object F = list.get(i).get("已拒绝") == null ? 0 : list.get(i).get("已拒绝");
                Object G = list.get(i).get("待审核") == null ? 0 : list.get(i).get("待审核");
                context.append(A).append(",").append(B).append(",").append(C).append(",").append(D)
                        .append(",").append(E).append(",").append(F).append(",").append(G)
                        .append("\n");
            }
        } else if ("ZP".equals(type)) {
            nowDate = "作品帖数.csv";
            context = new StringBuilder("日期,作品帖数（所有）,作品帖数（最终）,评委点评作品数,评委打分作品数\n");
            for (int i = 0; i < list.size(); i++) {
                Object A = list.get(i).get("date");
                Object B = list.get(i).get("作品帖数（所有）") == null ? 0 : list.get(i).get("作品帖数（所有）");
                Object C = list.get(i).get("作品帖数（最终）") == null ? 0 : list.get(i).get("作品帖数（最终）");
                Object D = list.get(i).get("评委点评作品数") == null ? 0 : list.get(i).get("评委点评作品数");
                Object E = list.get(i).get("评委打分作品数") == null ? 0 : list.get(i).get("评委打分作品数");
                context.append(A).append(",").append(B).append(",").append(C).append(",").append(D)
                        .append(",").append(E).append(",").append("\n");
            }
        } else if ("SF".equals(type)) {
            nowDate = "收费总数.csv";
            context = new StringBuilder("日期,报名收费,报名成功人数,商品售卖数,商品收费\n");
            for (int i = 0; i < list.size(); i++) {
                Object A = list.get(i).get("date");
                Object B = list.get(i).get("报名收费") == null ? 0 : list.get(i).get("报名收费");
                Object C = list.get(i).get("报名成功人数") == null ? 0 : list.get(i).get("报名成功人数");
                Object D = list.get(i).get("商品售卖数") == null ? 0 : list.get(i).get("商品售卖数");
                Object E = list.get(i).get("商品收费") == null ? 0 : list.get(i).get("商品收费");
                context.append(A).append(",").append(B).append(",").append(C).append(",").append(D)
                        .append(",").append(E).append(",").append("\n");
            }
        } else if ("LL".equals(type)) {
            nowDate = "浏览总数.csv";
            context = new StringBuilder("日期,帖子浏览数\n");
            for (int i = 0; i < list.size(); i++) {
                Object A = list.get(i).get("date");
                Object B = list.get(i).get("帖子浏览数") == null ? 0 : list.get(i).get("帖子浏览数");
                context.append(A).append(",").append(B).append("\n");
            }
        } else if ("DK".equals(type)) {
            nowDate = "打开总数.csv";
            context = new StringBuilder("日期,帖子打开数\n");
            for (int i = 0; i < list.size(); i++) {
                Object A = list.get(i).get("date");
                Object B = list.get(i).get("帖子打开数") == null ? 0 : list.get(i).get("帖子打开数");
                context.append(A).append(",").append(B).append("\n");
            }
        } else if ("HD".equals(type)) {
            nowDate = "互动总数.csv";
            context = new StringBuilder("日期,互动总数,点赞数量,打分数量,点评数量,讨论数量,投票数量\n");
            for (int i = 0; i < list.size(); i++) {
                Object A = list.get(i).get("date");
                Object B = list.get(i).get("互动总数") == null ? 0 : list.get(i).get("互动总数");
                Object C = list.get(i).get("点赞数量") == null ? 0 : list.get(i).get("点赞数量");
                Object D = list.get(i).get("打分数量") == null ? 0 : list.get(i).get("打分数量");
                Object E = list.get(i).get("点评数量") == null ? 0 : list.get(i).get("点评数量");
                Object F = list.get(i).get("讨论数量") == null ? 0 : list.get(i).get("讨论数量");
                Object G = list.get(i).get("投票数量") == null ? 0 : list.get(i).get("投票数量");
                context.append(A).append(",").append(B).append(",").append(C).append(",").append(D)
                        .append(",").append(E).append(",").append(F).append(",").append(G)
                        .append("\n");
            }
        }
        String fileName = new String(nowDate.getBytes("UTF-8"), "iso-8859-1");// 为了解决中文名称乱码问题
        OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        osw.write(new String(new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
        osw.write(context.toString());
        osw.flush();
    }


    private List<Object[]> getDataByType(String type, List<Long> evaluateIds, Date beginAt,
            Date endAt) {

        List<Object[]> objs = new ArrayList<>();
        if ("BM".equals(type)) {
            objs = evaluateApplyRepository.countByEvaluateIdInGroupByDays(beginAt, endAt,
                    evaluateIds);
        } else if ("ZP".equals(type)) {
            objs = evaluateApplyWorkRepository.countByEvaluateIdInGroupByDays(beginAt, endAt,
                    evaluateIds);
        } else if ("SF".equals(type)) {
            objs = orderRepository.countByEvaluateIdInGroupByDays(beginAt, endAt, evaluateIds);
        } else if ("LL".equals(type)) {
            objs = blogBehaviorRepository.countShowByEvaluateIdInGroupByDay(beginAt, endAt,
                    evaluateIds);
        } else if ("DK".equals(type)) {
            objs = blogBehaviorRepository.countOpendByEvaluateIdInGroupByDay(beginAt, endAt,
                    evaluateIds);
        } else if ("HD".equals(type)) {
            objs = blogBehaviorRepository.countHudongByEvaluateIdInGroupByDays(beginAt, endAt,
                    evaluateIds);
        }
        return objs;
    }

    private List<Map<String, Object>> getReturnList(Date beginAt, Date endAt, List<Object[]> objs) {

        List<Map<String, Object>> list = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(beginAt);
        while (cal.getTime().getTime() <= endAt.getTime()) {
            String nowDate = DateTimeUtil.format(cal.getTime(), DateTimeUtil.DATE_PATTERN_SHORT);
            Map<String, Object> map = new HashMap<>();
            for (Object[] os : objs) {
                Timestamp time = (Timestamp) os[0];
                String nTime = DateTimeUtil.format(new Date(time.getTime()),
                        DateTimeUtil.DATE_PATTERN_SHORT);
                if (nTime.equals(nowDate)) {
                    map.put(os[2].toString(), os[1]);
                }
            }
            map.put("date", nowDate + "(" + DateTimeUtil.getDaysInWeek(cal.getTime()) + ")");
            list.add(map);
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        Collections.sort(list, new Comparator<Map<String, Object>>() {
            public int compare(Map<String, Object> arg0, Map<String, Object> arg1) {
                return ((String) arg1.get("date")).compareTo(((String) arg0.get("date")));
            }
        });
        return list;
    }
}
